/*
 *Document   : Struts tutorial : http://netbeans.org/kb/docs/web/quickstart-webapps-struts.html#login
 */
package msse;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import bingSearch.Search;
import jsoup.JsoupExtract;
import googleSearch.GoogleSearch;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Arrays;
import java.util.HashMap;
import jsoup.CosineSimilarity;

import stemmingnaziefandriani.TextPreProcessing;
import TfIdf.TfIdf;
import Jama.Matrix; 
import Jama.SingularValueDecomposition;
import googleSearch.GoogleMain;

     
public class MSSEaction extends org.apache.struts.action.Action {

    /* forward name="success" path="" */
    private static final String SUCCESS = "success";
    private static final String FAILURE = "failure";


    /**
     * This is the action called from the Struts framework.
     *
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return
     */
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        
        MSSEform formBean = (MSSEform)form;
        String name = formBean.getName();
        ArrayList hasil= new ArrayList<String>();
        ArrayList hasil1= new ArrayList<String>();
        ArrayList hasil2= new ArrayList<String>();
        ArrayList hasil3= new ArrayList<String>();
        ArrayList<ArrayList<String>> temp = new ArrayList<ArrayList<String>>();
         ArrayList extract= new ArrayList<String>(); 
      ArrayList temp2= new ArrayList<String>(); 
      ArrayList temp4= new ArrayList<String>();
      ArrayList rank_doc= new ArrayList<String>();
      double [][] temp5;
      double [][] temp6;
      double [][] temp7;
      double [][] MatrixU;
      double [][] MatrixV;
      double [][] MatrixVT;
      double [][] MatrixS, MatrixSI, MatrixQT, QtUk, QtUkSi;
      double []hasil_cosine;
     
//        String query="Apa yang dimaksud dengan sistem informasi";
    //  ArrayList temp6= new ArrayList<String>(); 
      HashMap mapdoc = new HashMap<String, Integer>();
      HashMap mapquery = new HashMap<String, Integer>();
      
    //  String url = "http://asepsucipto.wordpress.com/2014/05/29/budaya-malu-ala-jepang/";
//      temp4.add("manajemen sistem informasi");		
//      temp4.add("sistem sumber daya manusia");		
//       temp4.add("manajemen informasi akademik");		

        
        if((name == null) ||  name.equals(""))
           {
            formBean.setError();
            return mapping.findForward(FAILURE);
            }
        else
        {
            
            GoogleSearch src2 = new GoogleSearch();
            hasil2=src2.SearchGoogle(name);
            System.out.print(src2);
            
         //  String url;
            Search src = new Search();
            hasil1=src.search(name);
            System.out.print(src);
          
            
            Collection<String> listOne = hasil1;
            Collection<String> listTwo = hasil2;
            Collection<String> similar = new HashSet<String>( listOne );
            Collection<String> different = new HashSet<String>();
            //menggabungkan 2 hasil dan tidak ada yang duplikasi URL dengan collection
            different.addAll( listOne );
            different.addAll( listTwo );
            hasil.addAll(different);
            formBean.setHasil(hasil);
           // request.setAttribute("hasil", hasil);
            //URL yang duplicate
            similar.retainAll( listTwo );
            JsoupExtract ext = new JsoupExtract();
             for (String s : different) {
             System.out.println("value= " + s);
             hasil3=ext.Extract(s);
             temp4.add(hasil3);
              }
              StringBuilder text = new StringBuilder();
         for (Object s : temp4)
        {
         text.append(s);
         text.append(" ");
        }
        
   // System.out.println(content.toString());
    //TextPreProcessing text = new TextPreProcessing();
    mapquery=TextPreProcessing.preprocessing(name);
    mapdoc=TextPreProcessing.preprocessing(text.toString());
   
    Object[] arrayquery = mapquery.keySet().toArray();
    Object[] arraydoc = mapdoc.keySet().toArray();
    int isi=arraydoc.length;
    int k=0;
    int l=0;
    double[][] MatrixQ = new double[1][isi];
    for(int i=0; i<arraydoc.length; i++)
    {
        for(int j=0; j<arrayquery.length; j++)
        {
            if (arraydoc[i].equals(arrayquery[j]))
            {
                MatrixQ[l][k]=1;
                
            }
        }
      k++;
    }
    MatrixQT=transposeMatrix(MatrixQ);
    temp5=TfIdf.TfIdf(temp4, mapdoc);
    
    temp6=transposeMatrix(temp5);
//    temp7=perkalianMatrix(temp6, temp5);
    
    //membuat matrix query
    
    
    
    
    //SVD
    
    Matrix A = new Matrix(temp6);         
        SingularValueDecomposition svd = new SingularValueDecomposition(A); 
       // Matrix ma = new Matrix(A);

        System.out.println("A = ");
        printMatrix(A);

        System.out.println("U = ");
        printMatrix(svd.getU());
        MatrixU=svd.getU().getArray();
        int Ukbaris=MatrixQT.length;
        int Ukkolom=MatrixU[0].length;
        double[][]MatrixUk= new double [Ukbaris][Ukkolom];
        
        for (int i=0; i<Ukbaris; i++)
        {
            
            for (int j=0; j<Ukkolom; j++)
            {
            double katak=MatrixU[i][j];
            MatrixUk[i][j]=katak;
         //   System.out.print(Matr);
            }
            
        }

        System.out.println("Sigma = ");
        printMatrix(svd.getS());
        MatrixS=svd.getS().getArray();
        
        //inverse matrix S
        System.out.println("S inverse = ");
        svd.getS().inverse();
        printMatrix(svd.getS().inverse());
        MatrixSI=svd.getS().inverse().getArray();
        
        System.out.println("V = ");
        printMatrix(svd.getV());
        MatrixV=svd.getV().getArray();
        
        System.out.println("Vt = ");
        MatrixVT=transposeMatrix(MatrixV);
       // printMatrix(MatrixVT);
    
   // System.out.println(temp5);
  //  System.out.println(temp6);
        
        //mencari matrik dokumen
        //MatriksQ * MatriksU
        QtUk=perkalianMatrix(MatrixQ, MatrixUk);
        QtUkSi=perkalianMatrix(QtUk, MatrixSI);
        
        int s=0;
        int index=MatrixVT.length;
      //  double[]rank_doc= new double [index];
        for (int i = 0 ; i < MatrixVT.length ; i++) 
        {   
            CosineSimilarity cos = new CosineSimilarity();
           // int t=0;
            int index2 = MatrixVT[0].length;
            double[]tempdoc = new double[index2];
            double[]tempque = new double[index2];
            for (int j = 0; j < MatrixVT[s].length; j++) 
            {
                double document = MatrixVT[i][j];
                double que = QtUkSi[0][j]; 
                tempdoc[j]=document;
                tempque[j]=que;
             //   System.out.println(tempdoc);
             //   t++;
            }
            double hasil_cos=cos.cosineSimilarity(tempque, tempdoc);
            System.out.println(hasil_cos);
            tempdoc=null;
            tempque=null;
          //  tempdoc = ArrayUtils.removeElement(tempdoc, i);
            rank_doc.add(hasil_cos);
            s++;
        }
        formBean.setRank(rank_doc); 
         // System.out.printf("One:%s%nTwo:%s%nSimilar:%s%nGabungan:%s%n", listOne, listTwo, similar, different);
        }
        
        return mapping.findForward(SUCCESS);
    }
    
     public static double[][] perkalianMatrix(double [][] m, double [][] n){ 
        int i, j, k, baris, kolom, panjang, x=0;
        baris=m.length;
        kolom=n[0].length;
        panjang=n.length;
       
          double[][] temp = new double[baris][kolom];
          for (i=0; i<baris; i++)
                {       
                     for (j=0; j<kolom; j++)
                        {
                            temp[i][j] = 0;   
                            for (k=0; k<panjang;  k++)
                            {
                            temp[i][j] += m[i][k] * n[k][j];
                     //       System.out.print(x);
                            x++;
                            }
                         }
              }
          for(i=0; i<baris; i++)
                {
                     for(j=0; j<kolom; j++)
                     {
                         //System.out.println("hasil tambah adalah:");
                         System.out.print(" "+ temp[i][j]);
                      }
                         System.out.println(" ");
                 }
        
        return temp;
    }
     
    
     
      static public void printMatrix(Matrix m){
        double[][] d = m.getArray();

        for(int row = 0; row < d.length; row++){
            for(int col = 0; col < d[row].length; col++){
                System.out.printf("%6.4f\t", m.get(row, col));
            }
            System.out.println();
        }
        System.out.println();
    }
      
      
      public static double[][] transposeMatrix(double [][] m){
        double[][] temp = new double[m[0].length][m.length];
        for (int i = 0; i < m.length; i++)
            for (int j = 0; j < m[0].length; j++)
                temp[j][i] = m[i][j];
        return temp;
    }
    
}
